import { IsString, IsNumber, IsOptional, IsBoolean, IsEthereumAddress, Min, Max, Length } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

export class CreateXLayerTokenDto {
  @ApiProperty({ description: 'Token name', example: 'MyToken' })
  @IsString()
  @Length(1, 32)
  name: string;

  @ApiProperty({ description: 'Token symbol', example: 'MTK' })
  @IsString()
  @Length(1, 10)
  symbol: string;

  @ApiProperty({ description: 'Token description', example: 'A revolutionary XLayer token' })
  @IsString()
  @Length(1, 500)
  description: string;

  @ApiPropertyOptional({ description: 'Website URL', example: 'https://mytoken.com' })
  @IsOptional()
  @IsString()
  website?: string;

  @ApiPropertyOptional({ description: 'Telegram URL', example: 'https://t.me/mytoken' })
  @IsOptional()
  @IsString()
  telegram?: string;

  @ApiPropertyOptional({ description: 'Twitter URL', example: 'https://twitter.com/mytoken' })
  @IsOptional()
  @IsString()
  twitter?: string;

  @ApiPropertyOptional({ description: 'Token image URL', example: 'https://mytoken.com/logo.png' })
  @IsOptional()
  @IsString()
  imageUrl?: string;

  @ApiProperty({ description: 'Target amount in ETH', example: 10.5 })
  @IsNumber()
  @Min(1)
  @Max(100)
  targetAmount: number;

  @ApiProperty({ description: 'Creator private key for signing transactions' })
  @IsString()
  creatorPrivateKey: string;
}

export class BuyXLayerTokenDto {
  @ApiProperty({ description: 'Launch ID of the token', example: 1 })
  @IsNumber()
  launchId: number;

  @ApiProperty({ description: 'ETH amount to spend', example: 1.5 })
  @IsNumber()
  @Min(0.001)
  ethAmount: number;

  @ApiProperty({ description: 'Buyer wallet address' })
  @IsEthereumAddress()
  buyerAddress: string;

  @ApiProperty({ description: 'Buyer private key for signing transaction' })
  @IsString()
  buyerPrivateKey: string;
}

// 新增：钱包签名版本的买入DTO
export class PrepareXLayerBuyDto {
  @ApiPropertyOptional({ description: 'Launch ID of the token', example: 1 })
  @IsOptional()
  @IsNumber()
  launchId?: number;

  @ApiProperty({ description: 'ETH amount to spend', example: 1.5 })
  @IsNumber()
  @Min(0.001)
  ethAmount: number;

  @ApiProperty({ description: 'Buyer wallet address' })
  @IsEthereumAddress()
  buyerAddress: string;
}

// 新增：钱包签名版本的卖出DTO
export class PrepareXLayerSellDto {
  @ApiPropertyOptional({ description: 'Launch ID of the token', example: 1 })
  @IsOptional()
  @IsNumber()
  launchId?: number;

  @ApiProperty({ description: 'Token amount to sell', example: 1000000 })
  @IsNumber()
  @Min(1)
  tokenAmount: number;

  @ApiProperty({ description: 'Seller wallet address' })
  @IsEthereumAddress()
  sellerAddress: string;
}

// 新增：代币授权DTO
export class PrepareXLayerApproveDto {
  @ApiPropertyOptional({ description: 'Launch ID of the token', example: 1 })
  @IsOptional()
  @IsNumber()
  launchId?: number;

  @ApiProperty({ description: 'Token amount to approve', example: 1000000 })
  @IsNumber()
  @Min(1)
  tokenAmount: number;

  @ApiProperty({ description: 'User wallet address' })
  @IsEthereumAddress()
  userAddress: string;
}

// 新增：确认购买交易DTO
export class ConfirmXLayerBuyDto {
  @ApiPropertyOptional({ description: 'Launch ID of the token', example: 1 })
  @IsOptional()
  @IsNumber()
  launchId?: number;

  @ApiProperty({ description: 'Transaction hash of the buy transaction' })
  @IsString()
  txHash: string;

  @ApiProperty({ description: 'Buyer wallet address' })
  @IsEthereumAddress()
  buyerAddress: string;

  @ApiProperty({ description: 'ETH amount spent', example: 1.5 })
  @IsNumber()
  @Min(0.001)
  ethAmount: number;
}

export class SellXLayerTokenDto {
  @ApiProperty({ description: 'Launch ID of the token', example: 1 })
  @IsNumber()
  launchId: number;

  @ApiProperty({ description: 'Token amount to sell', example: 1000000 })
  @IsNumber()
  @Min(1)
  tokenAmount: number;

  @ApiProperty({ description: 'Seller wallet address' })
  @IsEthereumAddress()
  sellerAddress: string;

  @ApiProperty({ description: 'Seller private key for signing transaction' })
  @IsString()
  sellerPrivateKey: string;
}

export class ContributeXLayerTokenDto {
  @ApiProperty({ description: 'Launch ID of the token', example: 1 })
  @IsNumber()
  launchId: number;

  @ApiProperty({ description: 'ETH amount to contribute', example: 2.0 })
  @IsNumber()
  @Min(0.01)
  ethAmount: number;

  @ApiProperty({ description: 'Contributor wallet address' })
  @IsEthereumAddress()
  contributorAddress: string;

  @ApiProperty({ description: 'Contributor private key for signing transaction' })
  @IsString()
  contributorPrivateKey: string;
}

export class GetXLayerTokensQueryDto {
  @ApiPropertyOptional({ description: 'Page number', example: 1, default: 1 })
  @IsOptional()
  @IsNumber()
  @Min(1)
  page: number = 1;

  @ApiPropertyOptional({ description: 'Number of items per page', example: 20, default: 20 })
  @IsOptional()
  @IsNumber()
  @Min(1)
  @Max(100)
  limit: number = 20;

  @ApiPropertyOptional({ description: 'Search term for token name or symbol' })
  @IsOptional()
  @IsString()
  search?: string;

  @ApiPropertyOptional({ 
    description: 'Filter tokens by status', 
    enum: ['all', 'active', 'launched', 'cancelled'],
    default: 'all'
  })
  @IsOptional()
  @IsString()
  filter?: 'all' | 'active' | 'launched' | 'cancelled' = 'all';

  @ApiPropertyOptional({ 
    description: 'Sort tokens by criteria', 
    enum: ['newest', 'oldest', 'price_high', 'price_low', 'market_cap', 'volume'],
    default: 'newest'
  })
  @IsOptional()
  @IsString()
  sort?: 'newest' | 'oldest' | 'price_high' | 'price_low' | 'market_cap' | 'volume' = 'newest';
}

export class UpdateXLayerTokenDto {
  @ApiPropertyOptional({ description: 'Updated description' })
  @IsOptional()
  @IsString()
  @Length(1, 500)
  description?: string;

  @ApiPropertyOptional({ description: 'Updated website URL' })
  @IsOptional()
  @IsString()
  website?: string;

  @ApiPropertyOptional({ description: 'Updated telegram URL' })
  @IsOptional()
  @IsString()
  telegram?: string;

  @ApiPropertyOptional({ description: 'Updated twitter URL' })
  @IsOptional()
  @IsString()
  twitter?: string;
}

export class GraduateXLayerTokenDto {
  @ApiProperty({ description: 'Launch ID of the token to graduate', example: 1 })
  @IsNumber()
  launchId: number;

  @ApiProperty({ description: 'Creator private key for signing transaction' })
  @IsString()
  creatorPrivateKey: string;
}

export class CancelXLayerTokenDto {
  @ApiProperty({ description: 'Launch ID of the token to cancel', example: 1 })
  @IsNumber()
  launchId: number;

  @ApiProperty({ description: 'Creator private key for signing transaction' })
  @IsString()
  creatorPrivateKey: string;
}

export class RefundXLayerTokenDto {
  @ApiProperty({ description: 'Launch ID of the token to claim refund from', example: 1 })
  @IsNumber()
  launchId: number;

  @ApiProperty({ description: 'User wallet address' })
  @IsEthereumAddress()
  userAddress: string;

  @ApiProperty({ description: 'User private key for signing transaction' })
  @IsString()
  userPrivateKey: string;
}

export class TradePreviewDto {
  @ApiProperty({ description: 'Launch ID of the token', example: 1 })
  @IsNumber()
  launchId: number;

  @ApiProperty({ description: 'User wallet address' })
  @IsEthereumAddress()
  userAddress: string;

  @ApiProperty({ description: 'Amount to trade (ETH for buy, tokens for sell)', example: 1.5 })
  @IsNumber()
  @Min(0.001)
  amount: number;

  @ApiProperty({ description: 'Trade type', enum: ['buy', 'sell'] })
  @IsString()
  type: 'buy' | 'sell';
}

export class PrepareXLayerCreateDto {
  @ApiProperty({ description: 'Token name', example: 'MyToken' })
  @IsString()
  @Length(1, 32)
  name: string;

  @ApiProperty({ description: 'Token symbol', example: 'MTK' })
  @IsString()
  @Length(1, 10)
  symbol: string;

  @ApiProperty({ description: 'Token description', example: 'A revolutionary XLayer token' })
  @IsString()
  @Length(1, 500)
  description: string;

  @ApiPropertyOptional({ description: 'Website URL', example: 'https://mytoken.com' })
  @IsOptional()
  @IsString()
  website?: string;

  @ApiPropertyOptional({ description: 'Telegram URL', example: 'https://t.me/mytoken' })
  @IsOptional()
  @IsString()
  telegram?: string;

  @ApiPropertyOptional({ description: 'Twitter URL', example: 'https://twitter.com/mytoken' })
  @IsOptional()
  @IsString()
  twitter?: string;

  @ApiPropertyOptional({ description: 'Token image URL', example: 'https://mytoken.com/logo.png' })
  @IsOptional()
  @IsString()
  imageUrl?: string;

  @ApiProperty({ description: 'Target amount in ETH', example: 10.5 })
  @IsNumber()
  @Min(1)
  @Max(100)
  targetAmount: number;

  @ApiProperty({ description: 'Creator wallet address' })
  @IsEthereumAddress()
  creatorAddress: string;
}

export class SyncXLayerTokenDto {
  @ApiProperty({ description: 'Launch ID of the token to sync', example: 1 })
  @IsNumber()
  launchId: number;
}

export class ConfirmXLayerCreateDto {
  @ApiProperty({ description: 'Transaction hash of the creation transaction' })
  @IsString()
  transactionHash: string;

  @ApiProperty({ description: 'Creator wallet address' })
  @IsEthereumAddress()
  creatorAddress: string;

  @ApiProperty({ description: 'Token name', example: 'MyToken' })
  @IsString()
  @Length(1, 32)
  name: string;

  @ApiProperty({ description: 'Token symbol', example: 'MTK' })
  @IsString()
  @Length(1, 10)
  symbol: string;

  @ApiProperty({ description: 'Token description', example: 'A revolutionary XLayer token' })
  @IsString()
  @Length(1, 500)
  description: string;

  @ApiPropertyOptional({ description: 'Website URL', example: 'https://mytoken.com' })
  @IsOptional()
  @IsString()
  website?: string;

  @ApiPropertyOptional({ description: 'Telegram URL', example: 'https://t.me/mytoken' })
  @IsOptional()
  @IsString()
  telegram?: string;

  @ApiPropertyOptional({ description: 'Twitter URL', example: 'https://twitter.com/mytoken' })
  @IsOptional()
  @IsString()
  twitter?: string;

  @ApiPropertyOptional({ description: 'Token image URL', example: 'https://mytoken.com/logo.png' })
  @IsOptional()
  @IsString()
  imageUrl?: string;

  @ApiProperty({ description: 'Target amount in ETH', example: 10.5 })
  @IsNumber()
  @Min(1)
  @Max(100)
  targetAmount: number;
}